/*
 * 
 */
package co.edu.udistrital.erpgrid.bd.modelo.connection;

import java.io.Serializable;

import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import co.edu.udistrital.erpgrid.bd.modelo.connection.api.ICrud;
import co.edu.udistrital.erpgrid.bd.modelo.pojo.GenericTable;
import co.edu.udistrital.erpgrid.exceptions.CrudException;

// TODO: Auto-generated Javadoc
/**
 * Servicio para operaciones de CRUD. Provee las operaciones basicas: creacion, modificacion,
 * eliminacion. <br>
 * 
 */
@Repository
@Transactional
public class CrudImpl implements ICrud {

  /** Variable LOG. para la salida del sistema*/
  private static org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(CrudImpl.class);

  /**
 * Manejador de Entidades.
 * @uml.property  name="entityManager"
 * @uml.associationEnd  readOnly="true"
 */
  @PersistenceContext
  private transient EntityManager entityManager;

  /*
   * (non-Javadoc)
   * 
   * @see co.gov.mme.mapper.dao.api.ICrud#save(co.gov.mme.mapper.entities.GenericTable )
   */
  public final GenericTable save(GenericTable entity) throws CrudException {
    try {
      LOG.debug("...persistiendo objeto : " + entity);
//      entityManager.persist(entity);
      GenericTable o = entityManager.merge(entity);
//      LOG.info(".. persistencia exitosa : " + ReflectionToStringEntityBuilder.toString(entity));
      return o;
    } catch (Exception e) {
    	LOG.error(e.getMessage(),e);
    	throw new CrudException(e);
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see co.gov.mme.mapper.dao.api.ICrud#delete(java.lang.Class, java.io.Serializable)
   */
  // @Transactional(readOnly = false, propagation = Propagation.REQUIRED)//cambia REQUIRES_NEW para
  // que no cree transacciones nuevas y se omite por que son valores por defecto.
  public void delete(Class entityType, Serializable id) throws CrudException {
    try {
      /* no funciona correctamente */
      // Object table = entityManager.getReference(entityType, id);
      Object table = entityManager.find(entityType, id);
      if (table == null) {
        throw new EntityNotFoundException("No existe El objeto " + entityType + "con Id=" + id);
      }
      LOG.info("...eliminando objeto de tipo: " + entityType + " , ID:" + id);
      entityManager.remove(table);
    } catch (Exception e) {
    	LOG.error(e.getMessage(),e);
    	throw new CrudException(e);
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see co.gov.mme.mapper.dao.api.ICrud#refresh(co.gov.mme.mapper.entities.GenericTable )
   */
  // @Transactional(readOnly = false, propagation = Propagation.REQUIRED)//cambia REQUIRES_NEW para
  // que no cree transacciones nuevas y se omite por que son valores por defecto.
  public final GenericTable refresh(GenericTable entity) throws CrudException {
    try {
      LOG.debug("...recargando objeto : " + entity);
      entityManager.refresh(entity);
//      LOG.info(".. refresh ejecutado : " + ReflectionToStringEntityBuilder.toString(entity));

      return entity;
    } catch (Exception e) {
    	LOG.error(e.getMessage(),e);
    	throw new CrudException(e);
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see co.gov.mme.mapper.dao.api.ICrud#flush( )
   */
  public void flush() throws CrudException {
    try {
      LOG.debug("flushing session.....");
      entityManager.flush();
    } catch (Exception e) {
      LOG.error(" FALLA flushing session.....", e);
      throw new CrudException(e);
    }
  }

}
